package com.linglan.common.config;

import cn.hutool.json.JSONUtil;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;

@Aspect
@Component
public class WebLogAspect {

    private final static Logger logger = LoggerFactory.getLogger(WebLogAspect.class);
    /** 换行符 */
    private static final String LINE_SEPARATOR = System.lineSeparator();

    @Pointcut("execution(* com.linglan.bff.controller..*.*(..))")
    public void webLog() {}

    private List<String> notLogUris = Arrays.asList("/third-api/callback/wechat_pay","/third-api/callback/wechat_refund",
            "/third-api/demorespheader1", "/third-api/callback/refund");
    /**
     * 在切点之前织入
     * @param joinPoint
     * @throws Throwable
     */
    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        // 开始打印请求日志
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();

        if (StringUtils.containsAnyIgnoreCase(request.getRequestURL().toString(), "/healthALBxxx")) {
//            // 打印请求相关参数
//            logger.info("========================================== Start ==========================================");
//            // 打印请求 url
//            logger.info("URL            : {}", request.getRequestURL().toString());
        } else {
            // 打印请求相关参数
            logger.info("========================================== Start ==========================================");
            // 打印请求 url
            logger.info("URL            : {}", request.getRequestURL().toString());
            // 打印描述信息
//        logger.info("Description    : {}", methodDescription);
            // 打印 Http method
            logger.info("HTTP Method    : {}", request.getMethod());
            // 打印调用 controller 的全路径以及执行方法
            logger.info("Class Method   : {}.{}", joinPoint.getSignature().getDeclaringTypeName(), joinPoint.getSignature().getName());
            // 打印请求的 IP
            logger.info("IP             : {}", request.getRemoteAddr());
            // 打印请求入参
            logger.info("fuck uir={}", request.getRequestURL().toString());
            if (!notLogUris.contains(request.getRequestURI())) {
                logger.info("Request Args   : {}", JSONUtil.toJsonStr(joinPoint.getArgs()));
            }
            logger.info("fuck uir3={}", request.getRequestURL().toString());
        }

    }

    public static void main(String[] args) {
        Object[] args11 = new Object[]{};
        System.out.println(JSONUtil.toJsonStr(args11));

    }

//    /**
//     * 在切点之后织入
//     * @throws Throwable
//     */
//    @After("webLog()")
//    public void doAfter() throws Throwable {
//        // 接口结束后换行，方便分割查看
//        logger.info("=========================================== End ===========================================" + LINE_SEPARATOR);
//    }

    /**
     * 环绕
     * @param proceedingJoinPoint
     * @return
     * @throws Throwable
     */
    @Around("webLog()")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object result = proceedingJoinPoint.proceed();
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        if (StringUtils.containsAnyIgnoreCase(request.getRequestURL().toString(), "/healthALBxxx")) {
            return result;
        } else {
            // 打印出参
            if (!notLogUris.contains(request.getRequestURI())) {
                logger.info("Response Args  : {}", JSONUtil.toJsonStr(result));
            }
            // 执行耗时
            long duration = System.currentTimeMillis() - startTime;
            logger.info("Time-Consuming : {} ms", duration);
            if (duration > 200) {
                logger.error("耗时过长 duration={}", duration);
            }
            logger.info("=========================================== End ===========================================" + LINE_SEPARATOR);
            return result;
        }
    }


    /**
     * 获取切面注解的描述
     *
     * @param joinPoint 切点
     * @return 描述信息
     * @throws Exception
     */
//    public String getAspectLogDescription(JoinPoint joinPoint)
//            throws Exception {
//        String targetName = joinPoint.getTarget().getClass().getName();
//        String methodName = joinPoint.getSignature().getName();
//        Object[] arguments = joinPoint.getArgs();
//        Class targetClass = Class.forName(targetName);
//        Method[] methods = targetClass.getMethods();
//        StringBuilder description = new StringBuilder("");
//        for (Method method : methods) {
//            if (method.getName().equals(methodName)) {
//                Class[] clazzs = method.getParameterTypes();
//                if (clazzs.length == arguments.length) {
//                    description.append(method.getAnnotation(WebLog.class).description());
//                    break;
//                }
//            }
//        }
//        return description.toString();
//    }
//
}
